import { compileToFunctions } from "./compiler";
import { callHook, mountComponent } from "./lifecycle";
import { initState } from "./state";
import { mergeOptions } from "./utils";

function getOuterHTML(el) {
    if (el.outerHTML) {
        return el.outerHTML;
    } else {
        var container = document.createElement('div');
        container.appendChild(el.cloneNode(true));
        return container.innerHTML;
    }
}

export function initMixin(Vue) {
    // 初始化
    Vue.prototype._init = function (options) {

        // 当前实例
        const vm = this;

        // 将定义的全局指令和过滤器都挂载到当前实例的 $options 上
        vm.$options = mergeOptions(this.constructor.options, options);

        // 创建前置钩子
        callHook(vm, 'beforeCreate');

        // 初始化状态
        initState(vm);

        // 创建完成后的钩子
        callHook(vm, 'created');

        // 挂载模板
        if (options.el) {
            vm.$mount(options.el);
        }
    }

    // 挂载模板
    Vue.prototype.$mount = function (el) {
        // 当前实例
        const vm = this;

        // 获取 el 元素
        el = document.querySelector(el);

        // 获取用户选项
        let ops = vm.$options;

        // 判断用户是否写了 render 方法
        if (!ops.render) {
            // 判断用户是否写了 template 模板，没有则使用 el 模板
            // let template = ops.template || getOuterHTML(el);
            let template;
            if (ops.template && el) {
                template = ops.template;
            } else {
                if (el) {
                    template = getOuterHTML(el);
                }
            }

            // 判断是否有模板
            if (template) {
                // 对模板进行编译的方法（将 HTML 转 JS）
                const render = compileToFunctions(template);
                // 将 render 挂载到 vm.$options 上
                ops.render = render;
            }
        }

        // 组件挂载
        mountComponent(vm, el);
    }
}